package com.xquant.pricing.calc.service.impl.otcOption.split;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.xquant.common.core.constant.DictConstant;
import com.xquant.pricing.calc.entity.CalcEngineParam4Simple;
import com.xquant.pricing.calc.entity.simple.*;
import com.xquant.common.engine.xPP.request.CalcEngineParam;
import com.xquant.common.engine.xPP.request.CalcPricingParam;
import com.xquant.common.engine.xPP.request.Instrument;
import org.springframework.stereotype.Component;

import java.util.List;


/**
 * 功能说明：二元期权拆分
 * 编写作者：botao.yu
 * 开发日期：2021/11/5 18:47
 * 修改记录：修改日期   修改人    修改内容
 */
@Component
public class CalcCommonService4OtcOptionSplit4Digital implements CalcCommonService4OtcOptionSplit {

    @Override
    public CalcEngineParam split(CalcEngineParam4Simple sourceCalcEngineParam) {
        {
            CalcEngineParam engineParam = new CalcEngineParam();
            engineParam.setPriority("h");
            engineParam.setLocalLog("1");
            Instrument instrument = new Instrument();
            Record record = sourceCalcEngineParam.getRecord();
            BaseInfo baseInfo = record.getBaseInfo();
            OptionTrade OptionTrade = record.getOptionTrade();
            String productType = null;
            List<PremiumItem> premiumList = null;
            if (OptionTrade != null) {
                premiumList = OptionTrade.getPremium();
            }
            List<OptionLeg> legDataList = OptionTrade.getOptionLegs();
            LegData legData = null;
            if (legDataList.size() > 0) {
                productType = legDataList.get(0).getProductType();
                legData = legDataList.get(0).getLegData();
            }
            if (legData != null) {
                JSONObject termData = new JSONObject();
                //普通交易+现金借贷的组合期权传入计算服务
                termData.put("notional", legData.getNotional());
                termData.put("notionalCurrency", "CNY");
                termData.put("term", legData.getTerm());
                termData.put("settlementType", "C");
                termData.put("settlementCurrency", "CNY");
                termData.put("effectiveDate", legData.getEffectiveDate());
                termData.put("effectiveDateConv", "Unadjusted");
                termData.put("terminationDate", legData.getTerminationDate());
                termData.put("terminationDateConv", "Unadjusted");
                termData.put("terminationDateCalendar", "CHINA_EX");
                legData.setUnderlyerId(getInstructionId((String) legData.getUnderlyerId()));
                String[] underLyerArray = {legData.getUnderlyerId()};
                termData.put("underlyerIds", underLyerArray);
                termData.put("calendars", new String[]{"CHINA_EX"});
                //记录腿号及方向
                JSONArray legsJsonArray = new JSONArray();
                JSONObject legsJSON = new JSONObject();
                legsJSON.put("legId", "leg01");
                legsJSON.put("payDirection", DictConstant.IR_DIRECT.SELL.equals(legData.getTrdType()) ? DictConstant.DIRECT.SELL : DictConstant.DIRECT.BUY);
                legsJsonArray.add(legsJSON);
                termData.put("legs", legsJsonArray);
                //拼装customeLeg
                JSONObject custLegsJSON = new JSONObject();
                custLegsJSON.put("participationRate", (String) legData.getParticipationRate());
                custLegsJSON.put("productType", DictConstant.OPTION_TYPE.DIGITAL.getCode());
                custLegsJSON.put("optionType", (String) legData.getOptionType());
                custLegsJSON.put("strikePercentage", (String) legData.getStrikeRate());
                custLegsJSON.put("numberOfOptions", "1");
                custLegsJSON.put("optionEntitlement", Double.parseDouble(legData.getNotional().toString()) / Double.parseDouble(legData.getSpotPrice().toString()));//标的份数=金额/标的初始价格
                custLegsJSON.put("moneynessOption", legData.getIfAnnual());//是否年化
                custLegsJSON.put("fixingRounding", "-1");//定盘精度
                custLegsJSON.put("settlementDateConv", "Unadjusted");//结算日调整
                custLegsJSON.put("settlementDateCalendar", "CHINA_EX");//结算日日历
                custLegsJSON.put("settlementDateOffset", (String) legData.getSettlementDateOffset() + "D");//结算日偏移
                custLegsJSON.put("legId", "leg01");//结算日日历
                JSONObject exerciseJSON = new JSONObject();
                exerciseJSON.put("type", "European");//默认欧式
                exerciseJSON.put("conv", "Unadjusted");//行权日调整方式
                exerciseJSON.put("calendar", "CHINA_EX");//行权日日历
                String[] exeDate = {legData.getTerminationDate()};//行权日
                exerciseJSON.put("dates", exeDate);
                custLegsJSON.put("exercise", exerciseJSON);
                //二元结构
                JSONObject digitalJSON = new JSONObject();
                digitalJSON.put("paymentDateOffset", (String) legData.getSettlementDateOffset() + "D");//结算日偏移
                digitalJSON.put("paymentDateConv", "Unadjusted");//行权日调整方式
                digitalJSON.put("paymentDateCalendar", "CHINA_EX");//行权日日历
                digitalJSON.put("paymentAmountPecentage", legData.getRebateRate());//支付水平 取补偿收益率
//            exerciseJSON.put("paymentAmount",legData);//支付金额
                JSONObject triggerJSON = new JSONObject();
                triggerJSON.put("type", "Greater");
                triggerJSON.put("levelPercentage", (String) legData.getStrikeRate());
                digitalJSON.put("trigger", triggerJSON);
                custLegsJSON.put("digital", digitalJSON);
                //标的结构
                JSONObject underLyerJSON = new JSONObject();
                JSONArray underLyerJSONArray = new JSONArray();
                underLyerJSON.put("instrumentId", legData.getUnderlyerId());
                underLyerJSON.put("quoteType", "");
                underLyerJSON.put("spotPrice", legData.getSpotPrice());//行权价格
                underLyerJSON.put("basketWeight", "1"); //权重
                underLyerJSON.put("fixingDate", legData.getFixingDate());//定盘日
                underLyerJSON.put("fixingDateConv", "Preceding");//定盘日调整
                underLyerJSON.put("fixingDateCalendar", "CHINA_EX");//定盘日日历
                underLyerJSONArray.add(underLyerJSON);
                custLegsJSON.put("underlyers", underLyerJSONArray);
                JSONArray custLegsArray = new JSONArray();
                custLegsArray.add(custLegsJSON);
                int i = 2;
                //期权费生成
                for (PremiumItem p : premiumList) {
                    JSONObject feeObj = getIRSteamObj(legData, p.getPaymentAmountRate());
                    feeObj.put("legId", "leg0" + i);
//                //根据期权费生成现金借贷
                    JSONObject legsJson = new JSONObject();
                    legsJson.put("legId", "leg0" + i);
                    legsJson.put("payDirection", DictConstant.DIRECT.SELL);
                    legsJsonArray.add(legsJson);
                    custLegsArray.add(feeObj);
                    i++;
                }
                //保底收益率增加现金借贷
                if (legData.getMinYield() != null && Double.parseDouble(legData.getMinYield()) > 0) {
                    JSONObject minObj = getIRSteamObj(legData, legData.getMinYield());
                    minObj.put("legId", "leg0" + i);
                    JSONObject legsJson = new JSONObject();
                    legsJson.put("legId", "leg0" + i);
                    legsJson.put("payDirection", DictConstant.IR_DIRECT.SELL.equals(legData.getTrdType()) ? DictConstant.DIRECT.SELL : DictConstant.DIRECT.BUY);
                    legsJsonArray.add(legsJson);
                    custLegsArray.add(minObj);
                }
                termData.put("customLegs", custLegsArray);
                instrument.setTermsheet(termData);
                instrument.setProductType(DictConstant.PRODUCT_TYPE.STRATEGY);
                engineParam.setInstrument(instrument);
                CalcPricingParam calPriceParamObj = new CalcPricingParam();
                calPriceParamObj.setValueDate(getCalcDate(sourceCalcEngineParam));
                JSON.toJSONString(calPriceParamObj);
                engineParam.setCalcPricingParam(calPriceParamObj);
                return engineParam;
            }
            return null;
        }
    }

    @Override
    public CalcEngineParam split(CalcEngineParam sourceCalcEngineParam) {
        return null;
    }

    @Override
    public String getSplitCode() {
        return DictConstant.OPTION_TYPE.DIGITAL.getCode();
    }


}
